package org.example.processors;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.google.auto.service.AutoService;
import org.example.anotations.TableCol;
import org.example.anotations.TableIndex;
import org.example.anotations.TableInfo;
import org.example.consts.MySQLDataType;

import javax.annotation.processing.Processor;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

@AutoService(Processor.class)
@SupportedAnnotationTypes({"org.example.anotations.EnableAutoGenerateSql"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class MysqlSqlGeneratorProcessor extends SqlGeneratorProcessor {
    @Override
    public void generateSqlFile(TypeElement element) {
        TableInfo tableInfo = element.getAnnotation(TableInfo.class);
        String tableName = tableInfo.name();
        StringBuilder sqlBuilder = new StringBuilder("CREATE TABLE ").append(tableName).append(" (\n");
        String primaryKeyName = null;
        for (Element enclosedElement : element.getEnclosedElements()) {
            if (enclosedElement.getKind() == ElementKind.FIELD) {
                TableCol tableCol = enclosedElement.getAnnotation(TableCol.class);
                if (tableCol != null) {
                    sqlBuilder.append("  ").append(tableCol.name()).append(" ").append(tableCol.type());
                    if (MySQLDataType.isLengthRequired(tableCol.type())) {
                        sqlBuilder.append(" (").append(tableCol.length()).append(") ");
                    }
                    if (StrUtil.isNotEmpty(tableCol.comment())) {
                        sqlBuilder.append(" COMMENT '").append(tableCol.comment()).append("'");
                    }
                    if (tableCol.primaryKey()) {
                        primaryKeyName = tableCol.name();
                    }
                    sqlBuilder.append(",\n");
                }
            }
        }
        if (StrUtil.isNotEmpty(primaryKeyName)) {
            sqlBuilder.append("PRIMARY KEY (").append(primaryKeyName).append(") \n");
        }
        sqlBuilder.append(");\n");

        //
        for (TableIndex index : tableInfo.indexes()) {
            sqlBuilder.append("CREATE ");
            if (index.unique()) {
                sqlBuilder.append("UNIQUE ");
            }
            sqlBuilder.append("INDEX ").append(index.name()).append(" ON ").append(tableName).append(" (");
            for (String column : index.columns()) {
                sqlBuilder.append(column).append(", ");
            }
            sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length());
            sqlBuilder.append(");\n");
        }

        try {
            String userDir = System.getProperty("user.dir");
            String sqlFilePath = userDir +File.separator +"generate-sql";
            File file = new File(sqlFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File sqlFile = new File(sqlFilePath, tableName + ".sql");
            try (PrintWriter out = new PrintWriter(sqlFile)) {
                out.print(sqlBuilder);
            }
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "SQL file generated: " + sqlFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
